package Agent;

import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import jade.core.behaviours.Behaviour;

public class ConnexionBehaviour extends Behaviour {

	int step;
	
	public ConnexionBehaviour()
	{
		step = 0;
	}
	
	@Override
	public void action() 
	{
		AgentBase agent = (AgentBase)getAgent();
		switch(step)
		{
			case 0 :
			{
				System.out.println("Connexion init");
				while(!agent.isConnected())
					agent.Connection();
				step++;
			}
			break;
			case 1 :
			{
				boolean actionToDo = false;
				while(!actionToDo)
				{
					try {
						actionToDo = checkRequest(agent.receiveDoc());
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						System.out.println("Probleme message reçu");
					}
				}
			}
			break;
			default :
		}
	}
	
	public boolean checkRequest(Document doc)
	{
		AgentBase  agent = (AgentBase)getAgent();
		
		if(doc == null)
			return false;
		else
		{
			Element root = (Element) doc.getDocumentElement();
			String type = root.getAttribute("type");
						
			if ( type.equalsIgnoreCase("sim-start") ) {
				
				agent.clearAllPercepts();
				agent.clearGoals();
				agent.clearBeliefs();
				
					NodeList tags = root.getElementsByTagName("simulation");
					checkPerceptSimStart(doc);
					Element tag = (Element) tags.item(0);
					String str = tag.getAttribute("role");
					if(!str.equals(agent.getRole()))
					{
						agent.doDelete();
						System.out.println("Erreur Role : "+agent.getRole()+" attendu "+str);
						return true;
					}
					return false;
						
			}
			else if ( type.equalsIgnoreCase("request-action") ) {
				String str = null;
				NodeList tags = root.getElementsByTagName("perception");
				assert tags.getLength() == 1;
				Element tag = (Element) tags.item(0);
				str = tag.getAttribute("id");
				assert str != null && str.equals("") == false;
				
				int id = Integer.parseInt(str);
				checkPerceptActionRequest(doc);
				
				/*if(agent.isVerbose())
					System.out.println("Id action : "+id);
				/*
				if(agent.getCurrentId()  == (id-1))
				{
					System.out.println("Erreur id action invalide");
				}
				 */
				agent.setCurrentId(id);
				return true;
				
			}
			else if ( type.equalsIgnoreCase("sim-end") ) {

				checkPerceptSimEnd(doc);
				return false;
				
			}
			else if ( type.equalsIgnoreCase("bye") ) 
			{
				getAgent().doDelete();
				return true;
			}
			else 
			{
				System.out.println("Message de type inconnu");
				return false;
			}
		}
	}

	@Override
	public boolean done() {
		// TODO Auto-generated method stub
		return false;
	}
	
	public void checkPerceptSimStart(Document doc)
	{
			AgentBase agent =(AgentBase)getAgent();
			
			Element root = doc.getDocumentElement();
			String str = null;
			assert root != null;
			assert root.getAttribute("type").equalsIgnoreCase("sim-start");

			Element simulation = (Element)root.getElementsByTagName("simulation").item(0);
			assert simulation.getNodeName().equalsIgnoreCase("simulation");
			
			str = simulation.getAttribute("id");
			assert str != null && str.equals("") == false;
			agent.addPercept("id", str);

			str = simulation.getAttribute("steps");
			assert str != null && str.equals("") == false;
			agent.addPercept("steps", str);
			
			str = simulation.getAttribute("vertices");
			assert str != null && str.equals("") == false;
			agent.addPercept("vertices", str);

			str = simulation.getAttribute("edges");
			assert str != null && str.equals("") == false;
			agent.addPercept("edges", str);

			str = simulation.getAttribute("role");
			assert str != null && str.equals("") == false;
			agent.addPercept("role", str);

	}

	public void checkPerceptActionRequest(Document doc)
	{
		String str;
		AgentBase agent = (AgentBase)getAgent();
		Element root = doc.getDocumentElement();
		
		assert root != null;
		assert root.getAttribute("type").equalsIgnoreCase("request-action");

		str = root.getAttribute("timestamp");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		long timestamp = new Long(str).longValue();
		agent.removePercepts("timestamp");
		agent.addPercept("timestamp", str);

		Element perception = (Element)root.getElementsByTagName("perception").item(0);
		assert perception.getNodeName().equalsIgnoreCase("perception");

		str = perception.getAttribute("deadline");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		long deadline = new Long(str).longValue();
		agent.removePercepts("deadline");
		agent.addPercept("deadline", str);
		
		NodeList tags;
		Element tag;
		int step;
		
		tags = perception.getElementsByTagName("simulation");
		assert tags.getLength() == 1 : Util.XMLToString(doc);
		tag = (Element) tags.item(0);
		
		str = tag.getAttribute("step");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		step = new Integer(str).intValue();
		agent.removePercepts("step");
		agent.addPercept("step", str);
		
		tags = perception.getElementsByTagName("self");
		assert tags.getLength() == 1;
		tag = (Element) tags.item(0);
		str = tag.getAttribute("zoneScore");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("zoneScore");
		agent.addPercept("zoneScore", str);
		
		str = tag.getAttribute("energy");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("energy");
		agent.addPercept("energy", str);

		str = tag.getAttribute("health");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("health");
		agent.addPercept("health", str);
		
		str = tag.getAttribute("lastAction");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("lastAction");
		agent.addPercept("lastAction", str);
		
		str = tag.getAttribute("lastActionParam");
		assert str != null : Util.XMLToString(doc);
		agent.removePercepts("lastActionParam");
		agent.addPercept("lastActionParam", str);

		str = tag.getAttribute("lastActionResult");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("lastActionResult");
		agent.addPercept("lastActionResult",str);

		str = tag.getAttribute("maxEnergy");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("maxEnergy");
		agent.addPercept("maxEnergy", str);
		
		str = tag.getAttribute("maxEnergyDisabled");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("maxEnergyDisabled");
		agent.addPercept("maxEnergyDisabled",str);
		
		str = tag.getAttribute("maxHealth");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("maxHealth");
		agent.addPercept("maxHealth", str);
		
		str = tag.getAttribute("position");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("position");
		agent.addPercept("position", str);
		
		str = tag.getAttribute("strength");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("strength");
		agent.addPercept("strength", str);
		
		str = tag.getAttribute("visRange");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("visRange");
		agent.addPercept("visRange", str);
		
		tags = perception.getElementsByTagName("team");
		assert tags.getLength() == 1;
		tag = (Element) tags.item(0);
		
		str = tag.getAttribute("money");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("money");
		agent.addPercept("money",str);
		
		str = tag.getAttribute("zonesScore");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("zoneScore");
		agent.addPercept("zoneScore", str);
		
		str = tag.getAttribute("lastStepScore");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("lastStepScore");
		agent.addPercept("lastStepScore",str);
		
		str = tag.getAttribute("score");
		assert str != null && str.equals("") == false : Util.XMLToString(doc);
		agent.removePercepts("score");
		agent.addPercept("score", str);
		
		tags = perception.getElementsByTagName("visibleVertices");
		assert tags.getLength() == 1;
		
		tag = (Element)tags.item(0);
		tags = tag.getElementsByTagName("visibleVertex");
		agent.removePercepts("visibleVertex");
		
		for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
			tag = (Element)tags.item(a);
			str = tag.getAttribute("name");
			assert str != null && str.equals("") == false : Util.XMLToString(doc);
			String name = new String(str);
			str = tag.getAttribute("team");
			assert str != null && str.equals("") == false : Util.XMLToString(doc);
			String team = new String(str);
			Percepts p = new Percepts("visibleVertex");
			p.addValue(name+" "+team);
			agent.addPercept(p);
		}

		tags = perception.getElementsByTagName("visibleEdges");
		assert tags.getLength() == 1;
		
		tag = (Element)tags.item(0);
		tags = tag.getElementsByTagName("visibleEdge");
		agent.removePercepts("visibleEdge");
		
		for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
			tag = (Element)tags.item(a);
			str = tag.getAttribute("node1");
			assert str != null && str.equals("") == false : Util.XMLToString(tag);
			String node1 = new String(str);
			str = tag.getAttribute("node2");
			assert str != null && str.equals("") == false : Util.XMLToString(tag);
			String node2 = new String(str);
			
			Percepts p = new Percepts("visibleEdge");
			p.addValue(node1+" "+node2);
			agent.addPercept(p);
		}
		
		// <visibleEntities>-tag and <visibleEntity>-tag
		tags = perception.getElementsByTagName("visibleEntities");
		agent.removePercepts("VisibleEntitie");
		if ( tags.getLength() != 0 ) {
			tag = (Element)tags.item(0);
			tags = tag.getElementsByTagName("visibleEntity");
			for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
				tag = (Element)tags.item(a);
				str = tag.getAttribute("name");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String name = new String(str);
				str = tag.getAttribute("node");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String node = new String(str);
				str = tag.getAttribute("team");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String team = new String(str);
				str = tag.getAttribute("status");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String status = new String(str);
				
				Percepts p = new Percepts("VisibleEntitie");
				p.addValue(name+" "+node+" "+team+" "+status);
				agent.addPercept(p);
			}
		}
		
		// <probedVertices>-tag and <probedVertex>-tag
		// <probedVertex name="vertex12" weight="8"/>
		tags = perception.getElementsByTagName("probedVertices");
		agent.removePercepts("probedVertice");
		if ( tags.getLength() != 0 ) {
			tag = (Element)tags.item(0);
			tags = tag.getElementsByTagName("probedVertex");
			for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
				tag = (Element)tags.item(a);
				str = tag.getAttribute("name");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String name = new String(str);
				str = tag.getAttribute("value");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String value = new String(str);
				Percepts p = new Percepts("probedVertice");
				p.addValue(name+" "+value);
				
				agent.addPercept(p);
			}
		}
		
		// <surveyedEdge node1="vertex12" node2="vertex19" weight="8"/>
		tags = perception.getElementsByTagName("surveyedEdges");
		if ( tags.getLength() != 0 ) {
			tag = (Element)tags.item(0);
			tags = tag.getElementsByTagName("surveyedEdge");
			for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
				tag = (Element)tags.item(a);
				str = tag.getAttribute("node1");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String node1 = new String(str);
				str = tag.getAttribute("node2");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String node2 = new String(str);
				str = tag.getAttribute("weight");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String weight = new String(str);
				
				agent.addPercept("surveyedEdge", node1 +" "+node2+" "+weight);
			}
		}
		
		// <inspectedEntity energy="8" health="9" maxEnergy="8" maxHealth="9" name="b4" node="vertex9" strength="6" team="B" visRange="2"/>
		tags = perception.getElementsByTagName("inspectedEntities");
		if ( tags.getLength() != 0 ) {
			tag = (Element)tags.item(0);
			tags = tag.getElementsByTagName("inspectedEntity");
			for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
				tag = (Element)tags.item(a);
			
				str = tag.getAttribute("name");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String name = new String(str);
				str = tag.getAttribute("team");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String team = new String(str);
				str = tag.getAttribute("role");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String role = new String(str);
				str = tag.getAttribute("node");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String node = new String(str);
				str = tag.getAttribute("energy");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String energy = new String(str);
				str = tag.getAttribute("maxEnergy");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String maxEnergy = new String(str);
				str = tag.getAttribute("health");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String health = new String(str);
				str = tag.getAttribute("maxHealth");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String maxHealth = new String(str);
				str = tag.getAttribute("strength");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String strength = new String(str);
				str = tag.getAttribute("visRange");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				String visRange = new String(str);

				agent.addPercept("inspectedEntity",name+" "+team+" "+role+" "+
							node+" "+energy+" "+maxEnergy+" "+health+" "+maxHealth+" "+strength+" "+visRange);
			}
		}

		// achievements
		tags = perception.getElementsByTagName("team");
		assert tags.getLength() == 1;
		tag = (Element) tags.item(0);
		tags = tag.getElementsByTagName("achievements");
		if ( tags.getLength() != 0 ) {
			tag = (Element)tags.item(0);
			tags = tag.getElementsByTagName("achievement");
			for ( int a = 0 ; a < tags.getLength() ; a ++ ) {
				tag = (Element)tags.item(a);
				str = tag.getAttribute("name");
				assert str != null && str.equals("") == false : Util.XMLToString(tag);
				agent.addPercept("achivement", str);
			}
		}
		
	}
	
	public void checkPerceptSimEnd(Document doc)
	{
			String str;
			AgentBase agent = (AgentBase)getAgent();
			Element root = doc.getDocumentElement();
			assert root != null;
			assert root.getAttribute("type").equalsIgnoreCase("sim-end");

			Element simResult = (Element)root.getElementsByTagName("sim-result").item(0);
			assert simResult.getNodeName().equalsIgnoreCase("sim-result");
			
			str = simResult.getAttribute("ranking");
			assert str != null && str.equals("") == false;
			agent.addPercept("ranking", str);

			str = simResult.getAttribute("score");
			assert str != null && str.equals("") == false;
			agent.addPercept("score", str);

	}

}
